
/**
 * Baijiahulian.com Inc. Copyright (c) 2014-2016 All Rights Reserved.
 */

package cn.wenhao.javaClassReload.constant;

import java.util.HashMap;
import java.util.Map;

import org.objectweb.asm.Type;

import cn.wenhao.javaClassReload.JavaClassModify.interfaces.ExecutorAccessor;
import cn.wenhao.javaClassReload.javaClassElements.FieldMember;
import cn.wenhao.javaClassReload.javaClassElements.ObjFieldMemberExecutor;
import lombok.extern.slf4j.Slf4j;

/**
 * @say little Boy, don't be sad.
 * @name Rezar
 * @time Oct 31, 2016
 * @Desc this guy is too lazy, nothing left.
 */
@Slf4j
public class ObjFieldMemberCache {

    private static final Map<String, ObjFieldMemberExecutor> objFieldMemberExecutors = new HashMap<>();

    private static final Map<String, FieldMember> reloadFieldMembers = new HashMap<>();

    /**
     * 
     * 设置非静态成员属性的值
     * 
     * @param string
     * @param string2
     * @param name
     */
    public static void putField(Object host, Object fieldValue, String fieldName) {
        // log.debug("host : {} is instanceof ExecutorAccessor : {} ", host, (host instanceof ExecutorAccessor));
        ObjFieldMemberExecutor objFieldMemberExecutor = null;
        if (host instanceof ExecutorAccessor) {
            ExecutorAccessor hostExecutor = (ExecutorAccessor) host;
            objFieldMemberExecutor = hostExecutor.getObjFieldMemberExecutor();
        } else if (host instanceof String) {
            String hostClass = (String) host;
            objFieldMemberExecutor = objFieldMemberExecutors.get(hostClass);
        }
        log.debug("objFieldMemberExecutor is : {} ", objFieldMemberExecutor);
        objFieldMemberExecutor.reSetField(objFieldMemberExecutor.register(fieldName), fieldValue);
    }

    /**
     * 
     * 获取非静态成员属性的值
     * 
     * @param string
     * @param string2
     * @param name
     */
    public static Object getField(Object host, String fieldName) {
        ObjFieldMemberExecutor objFieldMemberExecutor = null;
        if (host instanceof ExecutorAccessor) {
            ExecutorAccessor hostExecutor = (ExecutorAccessor) host;
            objFieldMemberExecutor = hostExecutor.getObjFieldMemberExecutor();
        } else if (host instanceof String) {
            String hostClass = (String) host;
            objFieldMemberExecutor = objFieldMemberExecutors.get(hostClass);
        }
        FieldMember fm = null;
        if ((fm = reloadFieldMembers.get(getReoladKey(host.getClass().getName(), fieldName))) != null) {
            objFieldMemberExecutor.replaceFieldMember(fm);
        }
        return objFieldMemberExecutor.invokeField(objFieldMemberExecutor.register(fieldName));
    }

    /**
     * 重新设置某个属性
     * 
     * @param hostClass
     * @param fm
     */
    public static void reloadableFieldMember(String hostClass, FieldMember fm) {
        reloadFieldMembers.put(getReoladKey(hostClass, fm.getName()), fm);
    }

    private static final String format = "%s:%s";

    /**
     * @param hostClass
     * @param name
     * @return
     */
    private static String getReoladKey(String hostClass, String name) {
        return String.format(format, hostClass, name);
    }

    /**
     * @param name
     * @param objFieldMemberExecutor
     */
    public static void registerObjFieldMember(String name, ObjFieldMemberExecutor objFieldMemberExecutor) {
        log.debug("register with name : {}  and objFieldMemberExecutor : {} ", name, objFieldMemberExecutor);
        objFieldMemberExecutors.put(name, objFieldMemberExecutor);
    }

    /**
     * 
     * @param hostClassName
     */
    public static ObjFieldMemberExecutor getObjFieldMember(Object hostClass) {
        ObjFieldMemberExecutor objFieldMemberExecutor =
            objFieldMemberExecutors.get(Type.getInternalName(hostClass.getClass()));
        if (objFieldMemberExecutor != null) {
            // 返回一个clone的类型
            return cloneObj(objFieldMemberExecutor);
        }
        return null;
    }

    private static ObjFieldMemberExecutor cloneObj(ObjFieldMemberExecutor objFieldMemberExecutor) {
        Map<Integer, FieldMember> allFieldMember = objFieldMemberExecutor.getAllFieldMember();
        // 如果是静态属性,不进行clone
        log.debug("size : {} ", allFieldMember.size());
        return objFieldMemberExecutor;
    }

}
